# -*- coding: UTF-8 -*-
import sys

sys.path.append("../Objets-Ali")
import batiment
import entite
              
class Action():
    def __init__(self, parent, frame, entiteId, systemeId, planeteId):
        self.parent = parent
        self.frame = frame
        self.entiteId = entiteId
        self.systemeId = systemeId
        self.planeteId = planeteId    


    def effectuerAction(self):
        pass
    
    #Recherche et retourne l'entite concernee avec son id
    def chercherEntite(self):
        for entite in parent.listeSystemes[self.systemeId].listePlanetes[self.planeteId].listeEntites:
            if entite.Id == self.entiteId:
                return entite
            
    def chercherPlanete(self):
        for planete in self.parent.listeSystemes[self.systemeId].listePlanetes:
            if planete.ID == self.planeteId:
                return planete
    def chercherSysteme(self):
        return self.parent.listeSystemes[self.systemeId]

            
    def verifierRessources(self, ressourcesTotal,cout):
        compteur = 0
        
        valide = True
        
        for prix in cout:
            if ressourcesTotal[compteur] - prix >= 0: 
                compteur = compteur + 1
            else:
                valide = False
                break
        
        if(valide):
            return True
        else:
            return False
            
            
           
class ActionDeplacement(Action):
    def __init__(self, parent, frame, entiteId, systemeId, planeteId, xFinal, yFinal, zFinal):
        Action.__init__(self, parent, frame, entiteId, systemeId, planeteId)
        self.xFinal = xFinal
        self.yFinal = yFinal
        self.zFinal = zFinal
        
    def effectuerAction(self):
        if self.planeteId == -1:
            entiteCourante = self.parent.listeSystemes[self.systemeId].trouverEntiteParId(self.entiteId)
        else:
            entiteCourante = self.parent.listeSystemes[self.systemeId].listePlanetes[self.planeteId].trouverEntiteParId(self.entiteId)
        
        if entiteCourante:
            prochaineAction = entiteCourante.deplacement(self.xFinal, self.yFinal, self.zFinal) #Liste des parametres retournes par la fonction mouvement
            
            if prochaineAction:
                entiteCourante.posX = prochaineAction[4]
                entiteCourante.posY = prochaineAction[5]
                entiteCourante.posZ = prochaineAction[6]
                
                self.frame = self.frame + 1
                
                entiteCourante.enDeplacement = True
                
                self.parent.controleur.ajouterOuModifierAction(self.parent.controleur.actionsAFaire, self)
                
#            else:
#                entiteCourante.enDeplacement = False
#                if self.planeteId != -1:
#                    self.parent.unitesAVerifierCollisions.append([entiteCourante, self.systemeId, self.planeteId])

class ActionAttaquer(Action):
    def __init__(self, parent, frame, entiteId, targetId, systemeId, planeteId):
        Action.__init__(self, parent, frame, entiteId, systemeId, planeteId)
        self.targetId = targetId
        
    def effectuerAction(self):
        #si on est sur une planète
        if self.planeteId != 0:
            entiteCourante = self.parent.listeSystemes[self.systemeId].listePlanetes[self.planeteId].trouverEntiteParId(self.entiteId)
            entiteTarget = self.parent.listeSystemes[self.systemeId].listePlanetes[self.planeteId].trouverEntiteParId(self.targetId)
        else:# si on est dans un système solaire
            entiteCourante = self.parent.listeSystemes[self.systemeId].trouverEntiteParId(self.entiteId)
            entiteTarget = self.parent.listeSystemes[self.systemeId].trouverEntiteParId(self.targetId)
        
        if entiteCourante and entiteTarget:
            frameProchaineAction = entiteCourante.attaquer(self.parent, entiteTarget, self.frame)
            
            if frameProchaineAction: 
                self.frame = frameProchaineAction
                self.parent.controleur.ajouterOuModifierAction(self.parent.controleur.actionsAFaire, self)
            
            if entiteTarget and entiteTarget.nbrVies <= 0:
                if self.planeteId != 0:
                    del self.parent.listeSystemes[self.systemeId].listePlanetes[self.planeteId].listeEntites[self.parent.listeSystemes[self.systemeId].listePlanetes[self.planeteId].listeEntites.index(entiteTarget)]
                else:
                    del self.parent.listeSystemes[self.systemeId].listeEntites[self.parent.listeSystemes[self.systemeId].listeEntites.index(entiteTarget)]

            #self.parent.unitesAVerifierCollisions.append([entiteCourante, self.systemeId, self.planeteId])
                
class ActionSortirPlanete(Action):
    def __init__(self, parent, frame, entiteId, systemeId, planeteId):
        Action.__init__(self, parent, frame, entiteId, systemeId, planeteId)
        
    def effectuerAction(self):
        xPlanete = self.chercherPlanete().posX
        yPlanete = self.chercherPlanete().posY
        entiteCourante = self.parent.listeSystemes[self.systemeId].listePlanetes[self.planeteId].trouverEntiteParId(self.entiteId)
        self.chercherPlanete().listeEntites.remove(entiteCourante)
        if((xPlanete - 50) < 50):
            entiteCourante.posX = (xPlanete + 50)
        else:
            entiteCourante.posX = (xPlanete - 50)
        entiteCourante.posY = yPlanete
        self.chercherPlanete().systemeParent.listeEntites.append(entiteCourante)

class ActionEntrerPlanete(Action):
    def __init__(self, parent, frame, entiteId, systemeId, planeteId):
        Action.__init__(self, parent, frame, entiteId, systemeId, planeteId)
        
    def effectuerAction(self):
        self.xFinal = self.parent.listeSystemes[self.systemeId].listePlanetes[self.planeteId].posX
        self.yFinal = self.parent.listeSystemes[self.systemeId].listePlanetes[self.planeteId].posY
        entiteCourante = self.parent.listeSystemes[self.systemeId].trouverEntiteParId(self.entiteId)

        if (entiteCourante.planetePossible == 1):
            if entiteCourante.posX != self.xFinal and  entiteCourante.posY != self.yFinal: #Deplacement
                prochaineAction = entiteCourante.deplacement(self.xFinal, self.yFinal, 0)
                if prochaineAction:
                    entiteCourante.posX = prochaineAction[4]
                    entiteCourante.posY = prochaineAction[5]
                    
                    self.frame = self.frame + 1
                    
                    entiteCourante.enDeplacement = True
                    
                    self.parent.controleur.ajouterOuModifierAction(self.parent.controleur.actionsAFaire, self)
                    
                else:
                    entiteCourante.enDeplacement = False
            else: #Arrive
                self.parent.listeSystemes[self.systemeId].listeEntites.remove(entiteCourante)
                entiteCourante.posX = 100
                entiteCourante.posY = 100
                entiteCourante.posZ = 0
                self.chercherPlanete().listeEntites.append(entiteCourante)       

class ActionChangerSysteme(Action):
    def __init__(self, parent, frame, entiteId, systemeCourant, systemeId, planeteId):
        Action.__init__(self, parent, frame, entiteId, systemeId, planeteId)
        self.systemeCourant = systemeCourant
        
    def effectuerAction(self):
        self.xFinal = self.parent.listeSystemes[self.systemeId].posX
        self.yFinal = self.parent.listeSystemes[self.systemeId].posY
        position = None
        #Regarde si l'objet est dans le systeme de depart ou entre deux systemes
        for objet in self.parent.listeSystemes[self.systemeCourant].listeEntites:
            if objet.id == self.entiteId:
                position = "Systeme"
                break;
            else:
                position = None
        if position == None:
            for objet in self.parent.listeEntites:
                if objet.id == self.entiteId:
                    position = "Galaxie"
                    break;
                else:
                    position = None
        if position == "Systeme": #Si dans le systeme, quitte vers la galaxie
            entiteCourante = self.parent.listeSystemes[self.systemeCourant].trouverEntiteParId(self.entiteId)
            self.parent.listeSystemes[self.systemeCourant].listeEntites.remove(entiteCourante)
            entiteCourante.posX = self.parent.listeSystemes[self.systemeCourant].posX
            entiteCourante.posY = self.parent.listeSystemes[self.systemeCourant].posY
            self.parent.listeEntites.append(entiteCourante)
            self.frame = self.frame + 1
            self.parent.controleur.ajouterOuModifierAction(self.parent.controleur.actionsAFaire, self)
        elif position == "Galaxie": #Si dans la galaxie, se deplace jusqua prochain systeme
            entiteCourante = self.parent.trouverEntiteParId(self.entiteId)
            if entiteCourante.posX != self.xFinal and  entiteCourante.posY != self.yFinal: #Deplacement
                prochaineAction = entiteCourante.deplacement(self.xFinal, self.yFinal, 0, 1)
                if prochaineAction:
                    entiteCourante.posX = prochaineAction[4]
                    entiteCourante.posY = prochaineAction[5]
                    
                    self.frame = self.frame + 1
                    
                    entiteCourante.enDeplacement = True
                    
                    self.parent.controleur.ajouterOuModifierAction(self.parent.controleur.actionsAFaire, self)
                else:
                    entiteCourante.enDeplacement = False
            else: #Arrive
                self.parent.listeEntites.remove(entiteCourante)
                self.parent.listeSystemes[self.systemeId].listeEntites.append(entiteCourante)
                
        else:
            print("Error")
    
#classe pr creer         
class ActionCreerUnite(Action):
    def __init__(self, parent, frame, entiteId, systemeId, planeteId, posX, posY, posZ, rallyX, rallyY, rallyZ, type, nomJoueur):
        Action.__init__(self, parent, frame, entiteId, systemeId, planeteId)
        
        
        self.posX = posX
        self.posY = posY
        self.posZ = posZ
        self.rallyX = rallyX
        self.rallyY = rallyY
        self.rallyZ = rallyZ
        self.type = type
        self.nomJoueur=nomJoueur

        
        #Ali: cette partie la est complete
    def effectuerAction(self):
    
        self.indexJoueur = self.parent.getIndexJoueur(self.nomJoueur)
        self.listeUpgrade = self.parent.joueur.listeUpgrades
        
        self.indexJoueur = self.parent.getIndexJoueur(self.nomJoueur)
        self.listeUpgrade = self.parent.joueur.listeUpgrades
        
        if self.planeteId != None:
            planet = self.chercherPlanete()
        else:
            planet = self.chercherSysteme()
        
        if self.type == "Tank":
            self.unite = entite.Tank(self.posX,self.posY,self.posZ, self.nomJoueur, self.entiteId)
            
            
            #pour les upgrades des unités créées
            
            planet.listeEntites.append(self.unite)
            
        if self.type == "Vaisseau":
            self.unite = entite.Vaisseau(self.posX,self.posY,self.posZ, self.nomJoueur, self.entiteId)
            planet.listeEntites.append(self.vaisseau)
            
        if self.type == "Explorateur":
            self.unite = entite.Explorateur(self.posX,self.posY,self.posZ, self.nomJoueur, self.entiteId)
            planet.listeEntites.append(self.unite)
            
        if self.type == "Transporteur":
            self.unite = entite.Transporteur(self.posX,self.posY,self.posZ, self.nomJoueur, self.entiteId)            
            planet.listeEntites.append(self.unite)
            
        if self.type == "Fregate":
            self.unite = entite.Fregate(self.posX,self.posY,self.posZ, self.nomJoueur, self.entiteId)            
            planet.listeEntites.append(self.unite)
            
        if self.type == "Colonisateur":
            self.unite = entite.Colonisateur(self.posX,self.posY,self.posZ, self.nomJoueur, self.entiteId)            
            planet.listeEntites.append(self.unite)
                        
        if self.type == "Croiseur":
            self.unite = entite.Croiseur(self.posX,self.posY,self.posZ, self.nomJoueur, self.entiteId)           
            planet.listeEntites.append(self.unite)
            
        if self.planeteId != None:
            monAction = ActionDeplacement(self.parent, self.frame+1, self.entiteId, self.systemeId, self.planeteId, self.rallyX, self.rallyY, self.rallyZ)
        else:
            monAction = ActionDeplacement(self.parent, self.frame+1, self.entiteId, self.systemeId, -1, self.rallyX, self.rallyY, self.rallyZ)
            
        #Pour upgrader toutes les unités que nous construisons si on a des upgrades
        self.unite.upgrade(self.indexJoueur, self.listeUpgrade)
        self.parent.controleur.ajouterOuModifierAction(self.parent.controleur.actionsAFaire, monAction )
       
            
class ActionCreerBatiment(Action):
    def __init__(self,parent,frame, entiteId,systemId, planeteId, Btype, posX, posY, posZ, nomJoueur):
        Action.__init__(self,parent, frame, entiteId, systemId, planeteId)
        
        self.type = Btype
        self.posX = posX
        self.posY = posY
        self.posZ = posZ
        self.nomJoueur=nomJoueur
        
    def effectuerAction(self):
        #nouveauId = self.genererId()
             
        planet = self.chercherPlanete()
        if self.type == "Mine":
            self.mine = batiment.Mine("Mine", "batiment", 
               60, 60, 60, self.posX, self.posY, self.posZ, 
               self.nomJoueur,100,self.entiteId)
            
            planet.listeEntites.append(self.mine)
        if self.type == "Habitation":
            self.habitation = batiment.Habitation("Habitation", "batiment", 
               60, 60, 60, self.posX, self.posY, self.posZ, 
               self.nomJoueur,100,self.entiteId)

            planet.listeEntites.append(self.habitation)
            
        if self.type == "Caserne":
            self.caserne = batiment.Caserne("Caserne", "batiment", 
               60, 60, 60, self.posX, self.posY, self.posZ, 
               self.nomJoueur,100,self.entiteId)
           
            
            planet.listeEntites.append(self.caserne)
            
        elif self.type == "Tour":
            self.tour = batiment.Tour("Tour","batiment", 
               60, 60, 60, self.posX, self.posY, self.posZ, 

               self.nomJoueur, 50, self.entiteId, 3, 10)
            
            
            planet.listeEntites.append(self.tour)
            
        elif self.type == "Usine":
            self.usine = batiment.Usine("Usine", "batiment",60 , 60, 60, self.posX,
                         self.posY, self.posZ, self.nomJoueur,100,self.entiteId)
            
            planet.listeEntites.append(self.usine)
            
            
        elif self.type == "Station Spatiale":
            self.station = batiment.StationSpatiale("Station Spatiale", "batiment",60, 60, 60, self.posX,
                         self.posY, self.posZ,self.nomJoueur,100,self.entiteId)
            
            self.chercherSysteme().listeEntites.append(self.station)   
            
        
        elif self.type == "Ferme":
            self.ferme = batiment.Ferme("Ferme", "batiment",60, 60, 60,self.posX,
                         self.posY, self.posZ, self.nomJoueur,100,self.entiteId)
            
            planet.listeEntites.append(self.ferme)
            
        
        elif self.type == "Centre de Recherche":
            self.centreRecherche = batiment.CentreRecherche("Centre de Recherche", "batiment",60, 60, 60, self.posX,
                         self.posY, self.posZ, self.nomJoueur,100,self.entiteId,0)
            
            planet.listeEntites.append(self.centreRecherche)
            
        elif self.type == "Centre de Communication":
            self.centreCommunication = batiment.CentreCommunication("Centre de Communication", "batiment",60, 60, 60, self.posX,
                         self.posY, self.posZ, self.nomJoueur,100,self.entiteId)
            
            planet.listeEntites.append(self.centreCommunication)
            
class ActionChangerStatus(Action):
    def __init__(self,parent, frame, entiteId, systemId, planeteId, nomJoueur1, nomJoueur2, newStatus):
        Action.__init__(self,parent, frame, entiteId, systemId, planeteId)
        self.nomJoueur1 = nomJoueur1
        self.nomJoueur2 = nomJoueur2
        self.newStatus = newStatus
        
    def effectuerAction(self):
        self.parent.joueur.modifierStatus(self.nomJoueur1,self.nomJoueur2,self.newStatus)
        

#Incrémente le compteur de 1 à chaque frame, pour compter le temps de création d'une unité
class ActionCompteur(Action):  
    def __init__(self,parent,frame, entiteId, systemId, planeteId, incrementeur,achat, unite, upgrade, posX, posY, posZ):#, joueur ):
        Action.__init__(self,parent, frame, entiteId, systemId, planeteId)
        
        #self.batiment = batiment
        #self.joueur = joueur
        self.unite = unite
        self.achat = achat
        self.upgrade = upgrade
        self.posX = posX
        self.posY = posY
        self.posZ = posZ
        
        #Pour une raison quelconque, je ne pouvais appeller la variable compteur
        self.compteur = incrementeur

        #Pour rappeller la méthode compteur jusqu'à ce que ça égal le nbr de frame besoin
        
        
    def effectuerAction(self):
           
            #si le compteur = au temps de creation de l'achat
        if self.compteur == self.parent.listePrix.getTempsCreation(self.achat):
            #si construction d'unite
            if self.unite != None:
                
                monAction = ActionCreerUnite(None, None, self.entiteId, self.systemeId, self.planeteId,self.batiment.rallyX ,self.batiment.rallyY, 0, self.unite.nom)
                
                
            elif self.upgrade != None:
                
                monAction = ActionUpgrade(None,self.parent.currentFrame + 1,0,0,0, self.achat, self.parent.joueur.nom, self.parent.getIndexJoueur(self.parent.joueur.nom))
                
            else:
                    
                monAction = ActionCreerBatiment(None, None, self.entiteId, self.systemeId, self.planeteId, self.batiment, self.posX, self.posY, self.posZ, self.joueur)
            
            #envoie laction au controleur pour qu'il l'execute ce qui crée l'unite ou un batiment
            self.parent.controleur.ajouterOuModifierAction(self.parent.controleur.actionsAEnvoyer, monAction )
            
        else:
            self.compteur=self.compteur+1
            self.frame += 1
            self.parent.controleur.ajouterOuModifierAction(self.parent.controleur.actionsAEnvoyer, ActionCompteur(None,self.parent.currentFrame + 1,0,0,0, self.compteur, self.achat, None, self.achat, 0, 0, 0) )
            #self.parent.controleur.ajouterOuModifierAction(self.parent.controleur.actionsAEnvoyer, self )  


class ActionUpgrade(Action):
    def __init__(self, parent, frame, entiteId, systemId, planeteId, achat,nomJoueur, indexJoueur):
        Action.__init__(self,parent, frame, entiteId, systemId, planeteId)
        
        self.achat = achat
        self.nomJoueur = nomJoueur
        self.indexJoueur = indexJoueur
        
        
    def effectuerAction(self):
        
        #if self.parent.joueur.nom == self.nomJoueur:
            
        if self.achat == "upgrade Explorateur":
            self.parent.joueur.listeUpgrades[self.indexJoueur][0] = True
        
        elif self.achat == "upgrade Fregate":
            self.parent.joueur.listeUpgrades[self.indexJoueur][1] = True
            
        elif self.achat == "upgrade Croiseur":
            self.parent.joueur.listeUpgrades[self.indexJoueur][2] = True
            #upgrade des armes
        elif self.achat[8] == "A":
            #détermine le niveau avec achat[12]
            self.upgrade(int(self.achat[12]), "Arme")
            #upgrade bouclier
        elif self.achat[8] == "B":
            self.upgrade(int(self.achat[16]), "Bouclier")
            
        
            
            
    def upgrade(self, niveau, type):
        if type == "Arme":
            if niveau == 1:
                self.parent.joueur.listeUpgrades[self.indexJoueur][3] = True
            
            elif niveau == 2:
                self.parent.joueur.listeUpgrades[self.indexJoueur][4] = True
                
            elif niveau == 3:
                self.parent.joueur.listeUpgrades[self.indexJoueur][5] = True
                
        else:
            if niveau == 1:
                self.parent.joueur.listeUpgrades[self.indexJoueur][6] = True
            
            elif niveau == 2:
                self.parent.joueur.listeUpgrades[self.indexJoueur][7] = True
                
            elif niveau == 3:
                self.parent.joueur.listeUpgrades[self.indexJoueur][8] = True
        
        for systeme in self.parent.listeSystemes:
            
            for planete in systeme.listePlanetes:
            
                for unite in planete.listeEntites:
                    if isinstance(unite,entite.Unite):
                        
                        if unite.joueur == self.nomJoueur:
                        
                            if type == "Arme":
                                unite.degat = unite.degat + 1
                                
                            
                            else:
                                unite.bouclier = unite.bouclier + 1
                
class ActionEnvoyerDemande(Action):
    #Le paramètre demande est une list de la forme [joueurCible,joueurDemandant, type, status]
    #joueurCible et joueurDemandant étant le nom des joueurs concernés
    def __init__(self,parent, frame, entiteId, systemId, planeteId, demande):
        Action.__init__(self,parent, frame, entiteId, systemId, planeteId)
        self.demande = demande
        
    def effectuerAction(self):
        self.parent.joueur.ajouterModifierDemande(self.demande[0], self.demande[1], self.demande[2], self.demande[3])
        
class ActionSupprimerDemande(Action):
    def __init__(self,parent, frame, entiteId, systemId, planeteId, demande):
        Action.__init__(self,parent, frame, entiteId, systemId, planeteId)
        self.demande = demande
        
    def effectuerAction(self):
        self.parent.joueur.supprimerDemande(self.demande)
        
class ActionNotificationDiplomatie(Action):
    def __init__(self,parent, frame, entiteId, systemId, planeteId, joueurCible):
        Action.__init__(self,parent, frame, entiteId, systemId, planeteId)
        self.joueurCible = joueurCible
    def effectuerAction(self):
        if(self.joueurCible == self.parent.joueur.nom):
            self.parent.joueur.notificationDiplomatie()
